package com.bodsite.rpc.thrift.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import org.apache.zookeeper.WatchedEvent;

import com.bodsite.common.logger.Logger;
import com.bodsite.common.logger.LoggerFactory;
import com.bodsite.rpc.spring.schema.bean.Zookeeper;
import com.bodsite.rpc.thrift.zk.BaseZkClient;

/**
 * 服务发现
 * @author bod
 * 2017年4月13日上午10:21:17
 */
public class ServiceDiscovery extends BaseZkClient{
	private static final Logger logger = LoggerFactory.getLogger(ServiceDiscovery.class);
	
	private final List<String> addressList = new ArrayList<String>();

	private final String serverPath;
	
	public ServiceDiscovery(String serverPath,Zookeeper zookeeper) throws Exception {
		this.serverPath = serverPath;
		this.zookeeperHost = zookeeper.getAddress();
		this.connect();
	}

	private void setAddressList() throws Exception{
		List<String> addressListNew = new ArrayList<String>();
		List<String> serviceNodes = getChildren(serverPath, true);
		if(serviceNodes!=null&&!serviceNodes.isEmpty()){
			for(String serviceNode:serviceNodes){
				String address = getData(serverPath+"/"+serviceNode, false);
				logger.info(" service address :"+serverPath+"/"+serviceNode+" data:"+address);
				addressListNew.add(address);
			}
		}
		addressList.clear();
		addressList.addAll(addressListNew);
	}
	
	
	@Override
	public void nodeChildrenChanged(WatchedEvent event) {
		if(serverPath.equals(event.getPath())){
			try {
				setAddressList();
			} catch (Exception e) {
				logger.error(" ServiceDiscovery nodeChildrenChanged error... serverPath:"+serverPath,e);
			}
		}
		
	}

	@Override
	public void connected(WatchedEvent event) {
		try {
			setAddressList();
		} catch (Exception e) {
			logger.error(" ServiceDiscovery connected error... serverPath:"+serverPath,e);
		}
	}

	public List<String> getAddressList() {
		return  Collections.unmodifiableList(addressList);
	}
	
	/**
	 * 获取地址 - 随机
	 * @author bod
	 * 2017年4月17日上午9:39:33
	 */
	public String getAddress(){
		int size = addressList.size();
		if(size==1){
			return addressList.get(0);
		}else if(size>0){
			int index = ThreadLocalRandom.current().nextInt(0, size);
			return addressList.get(index);
		}
		return null;
	}
	
}
